/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package documenteditor.controller;

import documenteditor.controller.exceptions.NonexistentEntityException;
import documenteditor.entidade.model.ClientePessoaFisica;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import documenteditor.entidade.model.CartaoFidelidade;
import documenteditor.entidade.model.Endereco;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Hibernate;

/**
 *
 * @author gleidson.moura
 */
public class ClientePessoaFisicaJpaController {

    public ClientePessoaFisicaJpaController() {
        emf = Persistence.createEntityManagerFactory("FidyCardPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(ClientePessoaFisica clientePessoaFisica) {
        if (clientePessoaFisica.getEnderecos() == null) {
            clientePessoaFisica.setEnderecos(new HashSet<Endereco>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            CartaoFidelidade cartaoFidelidade = clientePessoaFisica.getCartaoFidelidade();
            if (cartaoFidelidade != null) {
                cartaoFidelidade = em.getReference(cartaoFidelidade.getClass(), cartaoFidelidade.getIdCartaoFidelidade());
                clientePessoaFisica.setCartaoFidelidade(cartaoFidelidade);
            }
            Set<Endereco> attachedEnderecos = new HashSet<Endereco>();
            for (Endereco enderecosEnderecoToAttach : clientePessoaFisica.getEnderecos()) {
                enderecosEnderecoToAttach = em.getReference(enderecosEnderecoToAttach.getClass(), enderecosEnderecoToAttach.getIdEndereco());
                attachedEnderecos.add(enderecosEnderecoToAttach);
            }
            clientePessoaFisica.setEnderecos(attachedEnderecos);
            em.persist(clientePessoaFisica);
            if (cartaoFidelidade != null) {
                ClientePessoaFisica oldClienteOfCartaoFidelidade = (ClientePessoaFisica) cartaoFidelidade.getCliente();
                if (oldClienteOfCartaoFidelidade != null) {
                    oldClienteOfCartaoFidelidade.setCartaoFidelidade(null);
                    oldClienteOfCartaoFidelidade = em.merge(oldClienteOfCartaoFidelidade);
                }
                cartaoFidelidade.setCliente(clientePessoaFisica);
                cartaoFidelidade = em.merge(cartaoFidelidade);
            }
            for (Endereco enderecosEndereco : clientePessoaFisica.getEnderecos()) {
                enderecosEndereco.getClientes().add(clientePessoaFisica);
                enderecosEndereco = em.merge(enderecosEndereco);
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(ClientePessoaFisica clientePessoaFisica) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ClientePessoaFisica persistentClientePessoaFisica = em.find(ClientePessoaFisica.class, clientePessoaFisica.getIdCliente());
            CartaoFidelidade cartaoFidelidadeOld = persistentClientePessoaFisica.getCartaoFidelidade();
            CartaoFidelidade cartaoFidelidadeNew = clientePessoaFisica.getCartaoFidelidade();
            Set<Endereco> enderecosOld = persistentClientePessoaFisica.getEnderecos();
            Set<Endereco> enderecosNew = clientePessoaFisica.getEnderecos();
            if (cartaoFidelidadeNew != null) {
                cartaoFidelidadeNew = em.getReference(cartaoFidelidadeNew.getClass(), cartaoFidelidadeNew.getIdCartaoFidelidade());
                clientePessoaFisica.setCartaoFidelidade(cartaoFidelidadeNew);
            }
            Set<Endereco> attachedEnderecosNew = new HashSet<Endereco>();
            for (Endereco enderecosNewEnderecoToAttach : enderecosNew) {
                enderecosNewEnderecoToAttach = em.getReference(enderecosNewEnderecoToAttach.getClass(), enderecosNewEnderecoToAttach.getIdEndereco());
                attachedEnderecosNew.add(enderecosNewEnderecoToAttach);
            }
            enderecosNew = attachedEnderecosNew;
            clientePessoaFisica.setEnderecos(enderecosNew);
            clientePessoaFisica = em.merge(clientePessoaFisica);
            if (cartaoFidelidadeOld != null && !cartaoFidelidadeOld.equals(cartaoFidelidadeNew)) {
                cartaoFidelidadeOld.setCliente(null);
                cartaoFidelidadeOld = em.merge(cartaoFidelidadeOld);
            }
            if (cartaoFidelidadeNew != null && !cartaoFidelidadeNew.equals(cartaoFidelidadeOld)) {
                ClientePessoaFisica oldClienteOfCartaoFidelidade = (ClientePessoaFisica) cartaoFidelidadeNew.getCliente();
                if (oldClienteOfCartaoFidelidade != null) {
                    oldClienteOfCartaoFidelidade.setCartaoFidelidade(null);
                    oldClienteOfCartaoFidelidade = em.merge(oldClienteOfCartaoFidelidade);
                }
                cartaoFidelidadeNew.setCliente(clientePessoaFisica);
                cartaoFidelidadeNew = em.merge(cartaoFidelidadeNew);
            }
            for (Endereco enderecosOldEndereco : enderecosOld) {
                if (!enderecosNew.contains(enderecosOldEndereco)) {
                    enderecosOldEndereco.getClientes().remove(clientePessoaFisica);
                    enderecosOldEndereco = em.merge(enderecosOldEndereco);
                }
            }
            for (Endereco enderecosNewEndereco : enderecosNew) {
                if (!enderecosOld.contains(enderecosNewEndereco)) {
                    enderecosNewEndereco.getClientes().add(clientePessoaFisica);
                    enderecosNewEndereco = em.merge(enderecosNewEndereco);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = clientePessoaFisica.getIdCliente();
                if (findClientePessoaFisica(id) == null) {
                    throw new NonexistentEntityException("The clientePessoaFisica with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ClientePessoaFisica clientePessoaFisica;
            try {
                clientePessoaFisica = em.getReference(ClientePessoaFisica.class, id);
                clientePessoaFisica.getIdCliente();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The clientePessoaFisica with id " + id + " no longer exists.", enfe);
            }
            CartaoFidelidade cartaoFidelidade = clientePessoaFisica.getCartaoFidelidade();
            if (cartaoFidelidade != null) {
                cartaoFidelidade.setCliente(null);
                cartaoFidelidade = em.merge(cartaoFidelidade);
            }
            Set<Endereco> enderecos = clientePessoaFisica.getEnderecos();
            for (Endereco enderecosEndereco : enderecos) {
                enderecosEndereco.getClientes().remove(clientePessoaFisica);
                enderecosEndereco = em.merge(enderecosEndereco);
            }
            em.remove(clientePessoaFisica);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<ClientePessoaFisica> findClientePessoaFisicaEntities() {
        return findClientePessoaFisicaEntities(true, -1, -1);
    }

    public List<ClientePessoaFisica> findClientePessoaFisicaEntities(int maxResults, int firstResult) {
        return findClientePessoaFisicaEntities(false, maxResults, firstResult);
    }

    private List<ClientePessoaFisica> findClientePessoaFisicaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from ClientePessoaFisica as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public ClientePessoaFisica findClientePessoaFisica(Long id) {
        EntityManager em = getEntityManager();
        try {
            ClientePessoaFisica cliente = em.find(ClientePessoaFisica.class, id);
            Hibernate.initialize(cliente.getCartaoFidelidade().getPontoFidelidade());
            return cliente;
        } finally {
            em.close();
        }
    }

    public int getClientePessoaFisicaCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) em.createQuery("select count(o) from ClientePessoaFisica as o").getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
